package classes.gerais;

import java.io.BufferedReader;                          //Importação referente aos arquivos de persistência
import java.io.BufferedWriter;                          //Importação referente aos arquivos de persistência
import java.io.File;                                    //Importação referente aos arquivos de persistência
import java.io.FileNotFoundException;                   //Importação referente aos arquivos de persistência
import java.io.FileReader;                              //Importação referente aos arquivos de persistência
import java.io.FileWriter;                              //Importação referente aos arquivos de persistência
import java.io.IOException;                             //Importação de excessão
import java.util.logging.Level;                         //Importação para excessão
import java.util.logging.Logger;                        //Importação para excessão

public class Usuario {                                  //Classe que cadastra o usuário do sistema
    private String NomeDeUsuario;                       //NomeDeUsuario - Vulgo login, o que será necessário para entrar no sistema
    private String Senha;                               //Senha - Juntamente com o login, é necessária para entrar no sistema
    private String Nome;                                //Nome - Identificação do usuário
    private String Genero;                              //Genero - Gênero do usuário (masculi ou feminino)
    private int Idade;                                  //Idade - Idade do usuário
    
    public Usuario () {                                 //Montador caso não receba nenhuma informação
        this.NomeDeUsuario = null;                      //Setado como null, não há, ainda, a informação
        this.Senha = null;                              //Setado como null, não há, ainda, a informação
        this.Nome = null;                               //Setado como null, não há, ainda, a informação
        this.Genero = null;                             //Setado como null, não há, ainda, a informação
        this.Idade = 0;                                 //Setado como null, não há, ainda, a informação
    }
    
    public Usuario (String NDU, String SN, String NM, String GN, int NC) {      //Montador para quando as informações já estão disponíveis
        this.NomeDeUsuario = NDU;                                               //Insere o login
        this.Senha = SN;                                                        //Insere a senha do usuário
        this.Nome = NM;                                                         //Insere a identificação do usuário
        this.Genero = GN;                                                       //Insere a idade do usuário
        this.Idade = NC;                                                        //Insere a idade do usuário
    }
    
    public void InsereNDU (String NDU){                                         //Método que seta o login
        this.NomeDeUsuario = NDU;                                               //Seta o login
    }
    
    public void InsereSenha (String Senha){                                     //Método que seta a senha
        this.Senha = Senha;                                                     //Seta a senha
    }
    
    public void InsereNome (String NM){                                         //Método que seta a identificação
        this.Nome = NM;                                                         //Seta a identificação
    }
    
    public void InsereGenero (String GN){                                       //Método que seta o gênero
        this.Genero = GN;                                                       //Seta o gênero
    }
    
    public void InsereIdade (int NC){                                           //Método que seta a idade
        this.Idade = NC;                                                        //Seta a idade
    }
    
    public String DevolveNDU (){                                                //Método que retorna o login
        return NomeDeUsuario;                                                   //Retorna o login
    }
    
    public String DevolveSenha (){                                              //Método que retorna a senha
        return Senha;                                                           //Retorna a senha
    }
    
    public String DevolveNome (){                                               //Método que retorna a identificação
        return Nome;                                                            //Retorna a identificação
    }
    
    public String DevolveGenero (){                                             //Método que retorna o gênero
        return Genero;                                                          //Retorna o gênero
    }
    
    public int DevolveIdade (){                                                 //Método que retorna a idade
        return Idade;                                                           //Retorna a idade
    }
    
    public String Criptografa (){                                               //Método que implementa uma criptografia simples para a senha, afim de ter maior segurança quando persistida
        char [] Criptografia;                                                   //Vetor que pegará cada caractere para a criptografia individual
        String Final="";                                                        //String que guardará a senha criptografada
        int i;                                                                  //Variável de índice
        
        Criptografia = new char [Senha.length()];                               //Cria um vetor do tamanho da senha descriptografada
        Senha.getChars(0, Senha.length(), Criptografia, 0);                     //Recebe todos os caracteres da senha no vetor
        
        for (i = 0; i<Senha.length(); i++){                                     //Laço para criptografar, necessita acessar os índices poi modificaremos as posições acessadas
            if (Criptografia[i]>64 && Criptografia[i]<68){                      //Criptografa ABC
                Criptografia[i] = (char) (Criptografia[i]+1087);                //Insere chave de criptografia
            }
            if (Criptografia[i]>67 && Criptografia[i]<91){                      //Criptografa de D até Z
                Criptografia[i] = (char) (Criptografia[i]+546);                 //Insere chave de criptografia
            }
            if ((Criptografia[i]>0 && Criptografia[i]<65) || (Criptografia[i]>90 && Criptografia[i]<128)){      //Criptografa tudo que não faz parte do alfabeto
                Criptografia[i] = (char) (Criptografia[i]+246);                                                 //Insere chave de criptografia
            }
        }
        for (char Caracter : Criptografia){                                     //Para cada caracter no vetor
            Final += Caracter;                                                  //Monta a string
        }
        
    return Final;                                                               //Retorna a senha criptografada
    }
    
    public String Descriptografa (String Criptografado){                        //Método que descriptografa a senha do usuário
        char [] Criptografia;                                                   //Vetor que receberá os caracteres criptografados
        String Final="";                                                        //String que recupera a senha e a descriptografa
        int i;                                                                  //Variável de índice
        
        Criptografia = new char [Criptografado.length()];                       //Cria o vetor do char do tamanho da senha criptografada
        Criptografado.getChars(0, Criptografado.length(), Criptografia, 0);     //Recebre todos os caracteres da senha criptografada
        
        for (i = 0; i<Criptografado.length(); i++){                             //Laço para descriptografar, necessita acessar os índices poi modificaremos as posições acessadas
            if (Criptografia[i]>1151 && Criptografia[i]<1155){                  //Descriptografa ABC
                Criptografia[i] = (char) (Criptografia[i]-1087);                //Deschaveia o caractere
            }
            if (Criptografia[i]>613 && Criptografia[i]<637){                    //Descriptografa de D até Z
                Criptografia[i] = (char) (Criptografia[i]-546);                 //Deschaveia o caractere
            }
            if ((Criptografia[i]>246 && Criptografia[i]<311) || (Criptografia[i]>336 && Criptografia[i]<374)){      //Descriptografa tudo que não é alfabeto
                Criptografia[i] = (char) (Criptografia[i]-246);                                                     //Deschaveia o caractere
            }
        }
        
        for (char Caracter : Criptografia){                                     //Para cada caractere no vetor 
            Final += Caracter;                                                  //Insira na string da senha
        }
   
    return Final;                                                               //Retorna a senha descriptografada
    }
    
    public void PersisteUsuario () {                                                //Método que guarda os dados do usuário                            
        File ArqUsr = new File ("PUsuario.txt");                                    //Abre caminho para um arquivo

        try {                                                                       //Tente executar
            ArqUsr.createNewFile();                                                 //Criar um novo arquivo 
        } catch (IOException ex) {                                                  //Execssão caso não consiga criar
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);  //Solução fornecida pela IDE
        }
    
        FileWriter FWArqUsr;                                                        //Cria referência para um "escritor" para o arquivo
        try {                                                                       //Tente executar
            FWArqUsr = new FileWriter (ArqUsr);                                     //Criação do "escritor" para o arquivo                             
            try (BufferedWriter BWArqUsr = new BufferedWriter(FWArqUsr)) {          //Cria um outro escritor (usei esse porque da pra usar quebra de linha)
                FWArqUsr.write("");                                                 //Limpa o arquivo
                BWArqUsr.write(NomeDeUsuario);                                      //Insere o login
                BWArqUsr.newLine();                                                 //Quebra de linha
                BWArqUsr.write(Criptografa());                                      //Insere a senha criptografada
                BWArqUsr.newLine();                                                 //Quebra de linha
                BWArqUsr.write(Nome);                                               //Insere a identificação
                BWArqUsr.newLine();                                                 //Quebra de linha
                BWArqUsr.write(Genero);                                             //Insere o gênero
                BWArqUsr.newLine();                                                 //Quebra de linha
                BWArqUsr.write(String.valueOf(Idade));                              //Insere a idade transformada para uma string
            }
            FWArqUsr.close();                                                       //Fecha o arquivo
            
        } catch (IOException ex) {                                                  //Excessão de escrita
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);  //Solução fornecida pela IDE
        }   
    }
    
    public boolean RecuperaUsuario() {                                              //Método que recupera o usuário gravado no arquivo
        String Info;                                                                //Informação que será retirada do aqruivo
        BufferedReader BRArqUsr = null;                                             //Referência para um "leitor" de arquivos
        
        File Existencia = new File("PUsuario.txt");                                 //Caminho para um arquivo
        if (Existencia.exists() == false) return false;                             //Verifica se o arquivo existe, se não, retorna false, ou seja, não existe
        
        try {                                                                       //Tente executar
            BRArqUsr = new BufferedReader (new FileReader("PUsuario.txt"));         //Cria o "leitor" do arquivo
        } catch (FileNotFoundException ex) {                                        //Excessão caso não consiga criar o "leitor"
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);  //Solução fornecida pela IDE
        } 
        
        int Caminho = 1;                                                            //Variável que demonstrará o caminho para cada informação
        try {                                                                       //Tente executar
            while (BRArqUsr.ready()){                                               //Enquanto houverem linha sno arquivo
                Info = BRArqUsr.readLine();                                         //Info pega a informação da linha
                if (Caminho == 1) this.NomeDeUsuario = Info;                        //Se for o login, insere no login
                if (Caminho == 2) this.Senha = this.Descriptografa(Info);           //Se for a senha, descriptograva e insere na senha
                if (Caminho == 3) this.Nome = Info;                                 //Se for a identificação, insere na identificação
                if (Caminho == 4) this.Genero = Info;                               //Se for o gênero, insere no gênero
                if (Caminho == 5) this.Idade = Integer.parseInt(Info);              //Se for a idade, transforma em inteiro e insere na idade
                Caminho++;                                                          //Sabe-se que as informações estão em ordem, por isso incrementa-se o caminho a cada rodada
            }
        } catch (IOException ex) {                                                  //Excessão na manipulação do arquivo
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);  //Solução fornecida pela IDE
        }
        
        return true;                                                                //Retorna true, ou seja, a leitura foi um sucesso
    }
    
}